import pygame
from settings import *
from pytmx.util_pygame import load_pygame
from support import *
from random import choice

class SoilTile(pygame.sprite.Sprite):
	def __init__(self, pos, surf, groups):
		super().__init__(groups)
		self.image = surf
		self.rect = self.image.get_rect(topleft = pos)
		self.z = LAYERS['soil']

class WaterTile(pygame.sprite.Sprite):
	#  浇水土壤
	def __init__(self, pos, surf, groups):
		super().__init__(groups)
		self.image = surf
		self.rect = self.image.get_rect(topleft = pos)
		self.z = LAYERS['soil water']

class Plant(pygame.sprite.Sprite):
	#  种植
	def __init__(self, plant_type, groups, soil, check_watered):
		super().__init__(groups)
		
		# 设置
		self.plant_type = plant_type
		self.frames = import_folder(f'./graphics/fruit/{plant_type}')
		self.soil = soil
		self.check_watered = check_watered

		# 植物生长
		self.age = 0
		self.max_age = len(self.frames) - 1
		# 根据植物种类不同，获取不同的生长时间
		self.grow_speed = GROW_SPEED[plant_type]
		self.harvestable = False

		# 植物精灵
		self.image = self.frames[self.age]
		self.y_offset = -16 if plant_type == 'corn' else -8
		self.rect = self.image.get_rect(midbottom = soil.rect.midbottom + pygame.math.Vector2(0,self.y_offset))
		self.z = LAYERS['ground plant']

	def grow(self):
		# 植物生长
		if self.check_watered(self.rect.center):
			#  植物的年龄
			self.age += self.grow_speed

			if int(self.age) > 0:
				self.z = LAYERS['main']
				#  植物的碰撞体积
				self.hitbox = self.rect.copy().inflate(-26,-self.rect.height * 0.4)
			# 当他长到最大时，停止生长
			if self.age >= self.max_age:
				self.age = self.max_age
				self.harvestable = True

			self.image = self.frames[int(self.age)]
			self.rect = self.image.get_rect(midbottom = self.soil.rect.midbottom + pygame.math.Vector2(0,self.y_offset))

class SoilLayer:
	def __init__(self, all_sprites, collision_sprites):

		# 精灵组
		self.all_sprites = all_sprites
		self.collision_sprites = collision_sprites
		self.soil_sprites = pygame.sprite.Group()
		self.water_sprites = pygame.sprite.Group()
		self.plant_sprites = pygame.sprite.Group()

		# 图形
		self.soil_surfs = import_folder_dict('./graphics/soil/')
		self.water_surfs = import_folder('./graphics/soil_water')

		self.create_soil_grid()
		self.create_hit_rects()

		# 音频
		self.hoe_sound = pygame.mixer.Sound('./audio/hoe.wav')
		#  防止声音太大
		self.hoe_sound.set_volume(0.1)

		self.plant_sound = pygame.mixer.Sound('./audio/plant.wav')
		self.plant_sound.set_volume(0.2)

	def create_soil_grid(self):
		#  加载背景图
		ground = pygame.image.load('./graphics/world/ground.png')
		#  获取背景的宽和高
		h_tiles, v_tiles = ground.get_width() // TILE_SIZE, ground.get_height() // TILE_SIZE
		#  把整个地图，打印到列表中
		self.grid = [[[] for col in range(h_tiles)] for row in range(v_tiles)]
		#  把可以耕种的地块列表写入 F
		for x, y, _ in load_pygame('./data/map.tmx').get_layer_by_name('Farmable').tiles():
			self.grid[y][x].append('F')

	def create_hit_rects(self):
		#  当锄头耕地，替换耕地的泥土
		self.hit_rects = []
		for index_row, row in enumerate(self.grid):
			for index_col, cell in enumerate(row):
				if 'F' in cell:
					x = index_col * TILE_SIZE
					y = index_row * TILE_SIZE
					rect = pygame.Rect(x,y,TILE_SIZE, TILE_SIZE)
					self.hit_rects.append(rect)

	def get_hit(self, point):
		for rect in self.hit_rects:
			if rect.collidepoint(point):
				self.hoe_sound.play()

				x = rect.x // TILE_SIZE
				y = rect.y // TILE_SIZE
				#  如果处于下雨状态，那么耕地直接湿润
				if 'F' in self.grid[y][x]:
					self.grid[y][x].append('X')
					self.create_soil_tiles()
					if self.raining:
						self.water_all()

	def water(self, target_pos):
		for soil_sprite in self.soil_sprites.sprites():
			if soil_sprite.rect.collidepoint(target_pos):
				#  添加 W  到地图列表中代表这个是浇水的泥土
				x = soil_sprite.rect.x // TILE_SIZE
				y = soil_sprite.rect.y // TILE_SIZE
				self.grid[y][x].append('W')

				pos = soil_sprite.rect.topleft
				surf = choice(self.water_surfs)
				WaterTile(pos, surf, [self.all_sprites, self.water_sprites])

	def water_all(self):
		#  当遇到下雨天，土地自动水润
		for index_row, row in enumerate(self.grid):
			for index_col, cell in enumerate(row):
				if 'X' in cell and 'W' not in cell:
					cell.append('W')
					x = index_col * TILE_SIZE
					y = index_row * TILE_SIZE
					WaterTile((x,y), choice(self.water_surfs), [self.all_sprites, self.water_sprites])

	def remove_water(self):

		# 摧毁所有水精灵，当新的一天到来，才调用它
		for sprite in self.water_sprites.sprites():
			sprite.kill()

		# 清理网格
		for row in self.grid:
			for cell in row:
				if 'W' in cell:
					cell.remove('W')

	def check_watered(self, pos):
		# 判断是否是浇水的
		x = pos[0] // TILE_SIZE
		y = pos[1] // TILE_SIZE
		cell = self.grid[y][x]
		#  检测是否是有水的
		is_watered = 'W' in cell
		return is_watered

	def plant_seed(self, target_pos, seed):
		for soil_sprite in self.soil_sprites.sprites():
			if soil_sprite.rect.collidepoint(target_pos):
				self.plant_sound.play()

				x = soil_sprite.rect.x // TILE_SIZE
				y = soil_sprite.rect.y // TILE_SIZE

				if 'P' not in self.grid[y][x]:
					self.grid[y][x].append('P')
					Plant(seed, [self.all_sprites, self.plant_sprites, self.collision_sprites], soil_sprite, self.check_watered)

	def update_plants(self):
		for plant in self.plant_sprites.sprites():
			plant.grow()

	def create_soil_tiles(self):
		self.soil_sprites.empty()
		for index_row, row in enumerate(self.grid):
			for index_col, cell in enumerate(row):
				if 'X' in cell:
					
					# 耕地图像选择，根据不同的判断触发不同的图形
					t = 'X' in self.grid[index_row - 1][index_col]
					b = 'X' in self.grid[index_row + 1][index_col]
					r = 'X' in row[index_col + 1]
					l = 'X' in row[index_col - 1]
					#  默认耕地类型
					tile_type = 'o'

					# 耕地的四个面
					if all((t,r,b,l)): tile_type = 'x'

					# 仅限水平的耕地
					if l and not any((t,r,b)): tile_type = 'r'
					if r and not any((t,l,b)): tile_type = 'l'
					if r and l and not any((t,b)): tile_type = 'lr'

					# 仅限竖直的耕地
					if t and not any((r,l,b)): tile_type = 'b'
					if b and not any((r,l,t)): tile_type = 't'
					if b and t and not any((r,l)): tile_type = 'tb'

					# 角落的耕地
					if l and b and not any((t,r)): tile_type = 'tr'
					if r and b and not any((t,l)): tile_type = 'tl'
					if l and t and not any((b,r)): tile_type = 'br'
					if r and t and not any((b,l)): tile_type = 'bl'

					# T 型的耕地
					if all((t,b,r)) and not l: tile_type = 'tbr'
					if all((t,b,l)) and not r: tile_type = 'tbl'
					if all((l,r,t)) and not b: tile_type = 'lrb'
					if all((l,r,b)) and not t: tile_type = 'lrt'

					SoilTile(
						pos = (index_col * TILE_SIZE,index_row * TILE_SIZE), 
						surf = self.soil_surfs[tile_type], 
						groups = [self.all_sprites, self.soil_sprites])